import subprocess
from functools import partial

subprocess.Popen = partial(subprocess.Popen, encoding="utf-8")

import base64
import execjs

import time
import requests
from bs4 import BeautifulSoup
from fontTools.ttLib import TTFont
import re
import html

from common import settings


def fetch(page: int) -> (str, list[str]):
    cookies = {
        'Hm_lvt_434c501fe98c1a8ec74b813751d4e3e3': '1714036857',
        'sessionid': 'dd2pk7pguwqfkl6568wp8lfuvnuv6s8a',
        'Hm_lvt_9bcbda9cbf86757998a2339a0437208e': '1714381004,1714437986,1714464818,1714638753',
        'Hm_lpvt_9bcbda9cbf86757998a2339a0437208e': '1714638753',
        'Hm_lvt_c99546cf032aaa5a679230de9a95c7db': '1714437986,1714456622,1714464818,1714638753',
        'qpfccr': 'true',
        'no-alert3': 'true',
        'Hm_lpvt_c99546cf032aaa5a679230de9a95c7db': '1714638891',
    }

    headers = {
        'accept': 'application/json, text/javascript, */*; q=0.01',
        'accept-language': 'zh-CN,zh;q=0.9',
        'cache-control': 'no-cache',
        # 'cookie': 'Hm_lvt_434c501fe98c1a8ec74b813751d4e3e3=1714036857; sessionid=dd2pk7pguwqfkl6568wp8lfuvnuv6s8a; Hm_lvt_9bcbda9cbf86757998a2339a0437208e=1714381004,1714437986,1714464818,1714638753; Hm_lpvt_9bcbda9cbf86757998a2339a0437208e=1714638753; Hm_lvt_c99546cf032aaa5a679230de9a95c7db=1714437986,1714456622,1714464818,1714638753; qpfccr=true; no-alert3=true; Hm_lpvt_c99546cf032aaa5a679230de9a95c7db=1714638891',
        'pragma': 'no-cache',
        'priority': 'u=0, i',
        'referer': 'https://match.yuanrenxue.cn/match/7',
        'sec-ch-ua': '"Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Windows"',
        'sec-fetch-dest': 'empty',
        'sec-fetch-mode': 'cors',
        'sec-fetch-site': 'same-origin',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
        'x-requested-with': 'XMLHttpRequest',
    }

    params = {
        'page': page,
    }

    response = requests.get('https://match.yuanrenxue.cn/api/match/7', params=params
                            , cookies=cookies, headers=headers
                            # , verify=False
                            , proxies=settings.proxies
                            )
    text = response.text
    res = response.json()
    return res['woff'], [x['value'] for x in res['data']], text


class TtfHelper:
    def __init__(self, woff_path, woff, is_save_xml=False):
        self.parse_ttf(woff, woff_path)
        self.font = TTFont(woff_path)
        self.xml_path = woff_path.replace('.woff', '.xml')
        if is_save_xml:
            self.font.saveXML(self.xml_path)

    @staticmethod
    def string_to_hex(s: str):
        # ord() 函数返回字符的Unicode数值。hex() 函数用于将整数转换为十六进制字符串。
        return [hex(ord(x)) for x in s]

    def gen_code_to_info(self):
        document = open(self.xml_path, 'r', encoding='utf-8').read()
        cmap = re.findall('<map code="(.*?)" name="(.*?)"/>', document)
        ttf_dict = {}
        self.soup = BeautifulSoup(document, features='xml')
        for code, name in cmap:
            tt_glyph = self.soup.select_one(f'TTGlyph[name="{name}"]')
            ons = ''.join([x['on'] for x in tt_glyph.select(r'contour pt')])
            print(name, ons)
            ttf_dict[chr(eval(code))] = {
                'name': name,
                'code': code,
                # 'ons': ons,
                'num': TtfHelper.get_number_from_ons(ons),
            }
        self.ttf_dict = ttf_dict
        return ttf_dict

    def parse_ttf(self, woff: str, woff_path: str):
        woff_de = base64.b64decode(woff.strip())
        with open(woff_path, 'wb') as f:
            f.write(woff_de)

    def decode_string(self, score_string):
        nums = []
        for v in score_string:
            if len(v) == 0:
                continue
            v_temp = self.ttf_dict.get(html.unescape(v)).get('num')
            nums.append(str(v_temp))
        return ''.join(nums)

    @staticmethod
    def get_number_from_ons(on: str) -> int:
        res = [
            '10100100100101010010010010'
            , '1001101111'
            , '100110101001010101011110101000'
            , '10101100101000111100010101011010100101010100'
            , '111111111111111'
            , '1110101001001010110101010100101011111'
            , '10101010100001010111010101101010010101000'
            , '1111111'
            , '101010101101010001010101101010101010010010010101001000010'
            , '10010101001110101011010101010101000100100'
        ]
        return res.index(on)


def js(page, data):
    with open('success.js', 'r', encoding='utf-8') as f:
        js_file = f.read()
    ctx = execjs.compile(js_file)
    # args = [page, data]
    m = ctx.call('run', page, data)
    with open('success.html', 'w', encoding='utf-8') as f:
        f.write(m)


def parse_data(page, text, woff):
    js(page, text)
    ttf_helper = TtfHelper('woff.woff', woff, True)
    ttf_dict = ttf_helper.gen_code_to_info()
    items = []
    success_soup = BeautifulSoup(open('success.html', 'r', encoding='utf-8').read(), 'html.parser')
    for tr in success_soup.select('tr'):
        score_encry = tr.select_one('.fonteditor').text.replace('LP', '')
        score_decry = ttf_helper.decode_string(score_encry)
        name = tr.select_one('.ranking-li-span-3').text
        items.append({
            'name': name,
            'score': score_decry
        })
    return items


def main():
    lists = []
    for page in range(1, 6):
        time.sleep(0.5)
        woff, data, text = fetch(page)
        items = parse_data(page, text, woff)
        print(items)
        lists.extend(items)
    res = max(lists, key=lambda x: x['score'])
    print(res)
    # {'name': '冷视天下', 'score': '9711'}


if __name__ == '__main__':
    main()
